package types

// Reference: https://www.ietf.org/rfc/rfc4120.txt
// Section: 5.2.7
import (
	
	

	
	
)

// PAData implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7
type PAData struct {
	PADataType  int32  `asn1:"explicit,tag:1"`
	PADataValue []byte `asn1:"explicit,tag:2"`
}

// PADataSequence implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7
type PADataSequence []PAData

// MethodData implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.9.1
type MethodData []PAData

// PAEncTimestamp implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.2
type PAEncTimestamp EncryptedData

// PAEncTSEnc implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.2
type PAEncTSEnc struct {
	PATimestamp time.Time `asn1:"generalized,explicit,tag:0"`
	PAUSec      int       `asn1:"explicit,optional,tag:1"`
}

// Contains tests if a PADataSequence contains PA Data of a certain type.
func ( *PADataSequence) ( int32) bool {
	for ,  := range * {
		if .PADataType ==  {
			return true
		}
	}
	return false
}

// GetPAEncTSEncAsnMarshalled returns the bytes of a PAEncTSEnc.
func () ([]byte, error) {
	 := time.Now().UTC()
	 := PAEncTSEnc{
		PATimestamp: ,
		PAUSec:      int((.UnixNano() / int64(time.Microsecond)) - (.Unix() * 1e6)),
	}
	,  := asn1.Marshal()
	if  != nil {
		return , fmt.Errorf("error mashaling PAEncTSEnc: %v", )
	}
	return , nil
}

// ETypeInfoEntry implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.4
type ETypeInfoEntry struct {
	EType int32  `asn1:"explicit,tag:0"`
	Salt  []byte `asn1:"explicit,optional,tag:1"`
}

// ETypeInfo implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.4
type ETypeInfo []ETypeInfoEntry

// ETypeInfo2Entry implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.5
type ETypeInfo2Entry struct {
	EType     int32  `asn1:"explicit,tag:0"`
	Salt      string `asn1:"explicit,optional,generalstring,tag:1"`
	S2KParams []byte `asn1:"explicit,optional,tag:2"`
}

// ETypeInfo2 implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.5
type ETypeInfo2 []ETypeInfo2Entry

// PAReqEncPARep PA Data Type
type PAReqEncPARep struct {
	ChksumType int32  `asn1:"explicit,tag:0"`
	Chksum     []byte `asn1:"explicit,tag:1"`
}

// Unmarshal bytes into the PAData
func ( *PAData) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the PADataSequence
func ( *PADataSequence) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the PAReqEncPARep
func ( *PAReqEncPARep) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the PAEncTimestamp
func ( *PAEncTimestamp) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the PAEncTSEnc
func ( *PAEncTSEnc) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the ETypeInfo
func ( *ETypeInfo) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the ETypeInfoEntry
func ( *ETypeInfoEntry) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the ETypeInfo2
func ( *ETypeInfo2) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// Unmarshal bytes into the ETypeInfo2Entry
func ( *ETypeInfo2Entry) ( []byte) error {
	,  := asn1.Unmarshal(, )
	return 
}

// GetETypeInfo returns an ETypeInfo from the PAData.
func ( *PAData) () ( ETypeInfo,  error) {
	if .PADataType != patype.PA_ETYPE_INFO {
		 = fmt.Errorf("PAData does not contain PA EType Info data. TypeID Expected: %v; Actual: %v", patype.PA_ETYPE_INFO, .PADataType)
		return
	}
	_,  = asn1.Unmarshal(.PADataValue, &)
	return
}

// GetETypeInfo2 returns an ETypeInfo2 from the PAData.
func ( *PAData) () ( ETypeInfo2,  error) {
	if .PADataType != patype.PA_ETYPE_INFO2 {
		 = fmt.Errorf("PAData does not contain PA EType Info 2 data. TypeID Expected: %v; Actual: %v", patype.PA_ETYPE_INFO2, .PADataType)
		return
	}
	_,  = asn1.Unmarshal(.PADataValue, &)
	return
}